﻿using Autofac.Extensions.DependencyInjection;
using Autofac;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.IdentityModel.Tokens;
using Serilog;
using xjjxmm.infrastructure.Authorizations;
using xjjxmm.infrastructure.repository.impl.sugar;
using xjjxmm.infrastructure.repository.interfaces;
using xjjxmm.infrastructure.Webs;
using xjjxmm.infrastructure.xjjxmmLog.LogKit;
using XjjXmm.Infrastructure.Configuration;
using XjjXmm.Infrastructure.Constant;
using XjjXmm.Infrastructure.Jwt;
using XjjXmm.Infrastructure.User;
using XjjXmm.Infrastructure.Webs.ActionResult;
using xjjxmm.infrastructure.SetUp;
using SqlSugar;
using XjjXmm.Infrastructure.ToolKit;
using System.Reflection;
using xjjxmm.infrastructure.Common;

namespace xjjxmm.infrastructure.compont;

public class SqlCompont : ICompont
{
    public int Order { get; set; } = 100;



    public bool Regist(ContainerBuilder builder)
    {
        var configs = ConfigHelper.GetSection<List<DbConfig>>(CommonConstant.SqlConfigKey);
        if (configs?.Count == 1)
        {
            AddSql(builder, configs[0]);
            return true;
        }
        else  if(configs?.Count > 1) 
        {
            foreach (var item in configs)
            {
                AddSqlWithKey(builder, item);
            }
            return true;
        }

        return false;
    }

    private ContainerBuilder AddSql(ContainerBuilder builder, DbConfig dbConfig)
    {

        var dbtype = dbConfig.Type;
        var connectionString = dbConfig.ConnectionString;
        var frameConfig = ConfigHelper.GetSection<FrameworkConfig>(CommonConstant.FrameworkConfigKey);

        //Log.Information($"connectioin: {connectionString}");
        // Console.Write($"connectioin: {connectionString}");

        if (dbtype.IsNullOrEmpty() || connectionString.IsNullOrEmpty())
        {
            return builder;
        }


        builder.Register(com =>
        {
            return BuildSqlClient(connectionString!, dbtype!);
        }).AsImplementedInterfaces().SingleInstance();

        return builder;
       
    }

    private ContainerBuilder AddSqlWithKey(ContainerBuilder builder, DbConfig dbConfig)
    {
        var dbtype = ConfigHelper.GetConfig(dbConfig.Type!);
        var connectionString = ConfigHelper.GetConfig(dbConfig.ConnectionString!);
        var frameConfig = ConfigHelper.GetSection<FrameworkConfig>(CommonConstant.FrameworkConfigKey);

        //Log.Information($"connectioin: {connectionString}");
        // Console.Write($"connectioin: {connectionString}");

        if (dbtype.IsNullOrEmpty() || connectionString.IsNullOrEmpty())
        {
            return builder;
        }



        builder.Register(com =>
        {
            return BuildSqlClient(connectionString!, dbtype!);
        }).Keyed<ISqlSugarClient>(dbConfig.Key!).AsImplementedInterfaces().SingleInstance();

        return builder;
    }

    private SqlSugarScope BuildSqlClient(string connectionString, string dbtype)
    {

        var frameConfig = ConfigHelper.GetSection<FrameworkConfig>(CommonConstant.FrameworkConfigKey);


        var sqlSugar = new SqlSugarScope(new ConnectionConfig()
        {
            DbType = EnumKit.Parse<DbType>(dbtype!),
            ConnectionString = connectionString,
            IsAutoCloseConnection = true,
            ConfigureExternalServices = new ConfigureExternalServices
            {
                //注意:  这儿AOP设置不能少
                EntityService = (c, p) =>
                {
                    if (p.IsPrimarykey == false &&
                        new NullabilityInfoContext().Create(c).WriteState is NullabilityState.Nullable)
                    {
                        p.IsNullable = true;
                    }
                }
            }
        },
            db =>
            {
                if (frameConfig?.ShowSql == "1")
                {
                    //单例参数配置，所有上下文生效
                    db.Aop.OnLogExecuting = (sql, pars) =>
                    {
                        var par = pars?.Select(t => t.Value);

                        Log.Information($"Sql:{sql}\r\n paramters: {JsonKit.ToJson(par)}");
                        //Log.Information($"Sql:{sql}\r\n paramters: {JsonConvert.SerializeObject(pars)}");
                        //Console.WriteLine(sql);//输出sql
                        //Console.WriteLine(string.Join(",", pars?.Select(it => it.ParameterName + ":" + it.Value)));//参数
                    };
                }

                db.Aop.OnError = exception => { Log.Error(exception, "sql error"); };
            }
        );

        return sqlSugar;

    }
}
